import unittest
import os
import glob
import email
from mailbox import mboxMessage, mbox

import main

class MainTest(unittest.TestCase):
    def setUp(self):
        self.filename = "mboxtest"
        self.mbox = mbox(self.filename)
        
    def tearDown(self):
        for question_file in glob.glob("*.question"):
            os.remove(question_file)
            
        for emails_file in glob.glob("*.emails"):
            os.remove(emails_file)
            
        os.remove(self.filename)
        
        try:
            os.remove(self.filename + ".out")
        except OSError:
            pass
        
    def test_prepare_one_thread(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        self.mbox.add(email1)
        self.mbox.flush()
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
        self.mbox.add(email2)
        self.mbox.flush()
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
        self.mbox.add(email3)
        self.mbox.flush()
        
        email4 = mboxMessage()
        email4["message-id"] = "4"
        email4["from"] = email.utils.formataddr(("Ana", "ana@presley.com"))
        email4["subject"] = "root email for test"
        email4["references"] = "1"
        email4.set_payload("other test :D")
        self.mbox.add(email4)
        self.mbox.flush()
        
        main.prepare(self.filename)
        
        question_files = glob.glob("*.question")
        email_files = glob.glob("*.emails")
        
        question = open(question_files[0])
        question_sections = question.read().split("\n", 3)
        self.assertEquals(email1["from"], question_sections[0])
        self.assertEquals("No date specified", question_sections[1])
        self.assertEquals(email1["subject"], question_sections[2])
        self.assertEquals(email1.get_payload(), question_sections[3])
        
        replys = open(email_files[0])
        reply_emails = replys.readlines()
        
        #removing \n's
        reply_emails = [e.strip() for e in reply_emails]
        
        self.assertEquals(3, len(reply_emails))
        self.assertTrue("maria@presley.com" in reply_emails)
        self.assertTrue("joao@presley.com" in reply_emails)
        self.assertTrue("ana@presley.com" in reply_emails)
        
        
    def test_prepare_two_threads(self):
        
        # first thread
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        self.mbox.add(email1)
        self.mbox.flush()
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
        self.mbox.add(email2)
        self.mbox.flush()
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
        self.mbox.add(email3)
        self.mbox.flush()
        
        # second thread
        
        email4 = mboxMessage()
        email4["message-id"] = "4"
        email4["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email4["subject"] = "A new thread starts here"
        email4.set_payload("A brand new thread to test")
        self.mbox.add(email4)
        self.mbox.flush()
        
        email5 = mboxMessage()
        email5["message-id"] = "5"
        email5["from"] = email.utils.formataddr(("Ana", "ana@presley.com"))
        email5["subject"] = "RE: A new thread starts here"
        email5["references"] = "4"
        email5.set_payload("Omg, finnaly a new thread")
        self.mbox.add(email5)
        self.mbox.flush()
        
        email6 = mboxMessage()
        email6["message-id"] = "6"
        email6["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email6["subject"] = "RE: A new thread starts here"
        email6["references"] = "4"
        email6.set_payload("I'm tired, this thread will have only 3 messages.")
        self.mbox.add(email6)
        self.mbox.flush()
        
        main.prepare(self.filename)
        
        question_files = glob.glob("*.question")
        question_files.sort()
        
        email_files = glob.glob("*.emails")
        email_files.sort()
        
        # first thread asserts
        
        question = open(question_files[0])
        question_sections = question.read().split("\n", 3)
        self.assertEquals(email1["from"], question_sections[0])
        self.assertEquals("No date specified", question_sections[1])
        self.assertEquals(email1["subject"], question_sections[2])
        self.assertEquals(email1.get_payload(), question_sections[3])
        
        replys = open(email_files[0])
        reply_emails = replys.readlines()
        
        #removing \n's
        reply_emails = [e.strip() for e in reply_emails]
        
        self.assertEquals(2, len(reply_emails))
        self.assertTrue("maria@presley.com" in reply_emails)
        self.assertTrue("joao@presley.com" in reply_emails)
        
        # second thread asserts
        
        question = open(question_files[1])
        question_sections = question.read().split("\n", 3)
        self.assertEquals(email4["from"], question_sections[0])
        self.assertEquals("No date specified", question_sections[1])
        self.assertEquals(email4["subject"], question_sections[2])
        self.assertEquals(email4.get_payload(), question_sections[3])
        
        replys = open(email_files[1])
        reply_emails = replys.readlines()
        
        #removing \n's
        reply_emails = [e.strip() for e in reply_emails]
        
        self.assertEquals(2, len(reply_emails))
        self.assertTrue("ana@presley.com" in reply_emails)
        self.assertTrue("jose@presley.com" in reply_emails)
    
    
    def test_remove_one_thread(self):
        # create original file
        
        # first thread
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        self.mbox.add(email1)
        self.mbox.flush()
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
        self.mbox.add(email2)
        self.mbox.flush()
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
        self.mbox.add(email3)
        self.mbox.flush()
        
        # second thread
        
        email4 = mboxMessage()
        email4["message-id"] = "4"
        email4["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email4["subject"] = "A new thread starts here"
        email4.set_payload("A brand new thread to test")
        self.mbox.add(email4)
        self.mbox.flush()
        
        email5 = mboxMessage()
        email5["message-id"] = "5"
        email5["from"] = email.utils.formataddr(("Ana", "ana@presley.com"))
        email5["subject"] = "RE: A new thread starts here"
        email5["references"] = "4"
        email5.set_payload("Omg, finnaly a new thread")
        self.mbox.add(email5)
        self.mbox.flush()
        
        email6 = mboxMessage()
        email6["message-id"] = "6"
        email6["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email6["subject"] = "RE: A new thread starts here"
        email6["references"] = "4"
        email6.set_payload("I'm tired, this thread will have only 3 messages.")
        self.mbox.add(email6)
        self.mbox.flush()
        
        main.remove("maria@presley.com", self.filename, self.filename + ".out")
        
        result_mbox = mbox("mboxtest.out")
        
        message_id_list = []
        
        for msg in result_mbox:
            message_id_list.append(msg["message-id"])
        
        self.assertEquals(3, len(result_mbox))
        self.assertTrue(email4["message-id"] in message_id_list)
        self.assertTrue(email5["message-id"] in message_id_list)
        self.assertTrue(email6["message-id"] in message_id_list)
